package com.cltech.service.sys.impl;


import com.cltech.constant.UserState;
import com.cltech.dto.SysUserDto;
import com.cltech.entity.sys.SysPermission;
import com.cltech.entity.sys.SysRole;
import com.cltech.entity.sys.SysUser;
import com.cltech.frame.base.impl.BaseServiceImpl;
import com.cltech.frame.result.ResponseBean;
import com.cltech.frame.shiro.Token;
import com.cltech.frame.specification.utils.SpecificationSortUtil;
import com.cltech.frame.utils.JWTUtil;
import com.cltech.mapper.SysUserMapper;
import com.cltech.repository.sys.SysUserRepository;
import com.cltech.service.sys.SysOrganizationService;
import com.cltech.service.sys.SysRoleService;
import com.cltech.service.sys.SysUserService;
import com.cltech.util.PasswordUtil;
import com.google.common.base.Splitter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import static java.util.stream.Collectors.toSet;

/**
 * Created by Administrator on 2018/9/9.
 */
@Service("sysUserService")
public class SysUserServiceImpl extends BaseServiceImpl<SysUser, String> implements SysUserService {
    private SysUserRepository sysUserRepository;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysOrganizationService sysOrganizationService;
    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    public void setSysUserRepository(SysUserRepository sysUserRepository) {
        this.sysUserRepository = sysUserRepository;
        super.setBaseRepository(sysUserRepository);
    }

    @Override
    public ResponseBean<SysUser> findByAccountAndState(String account, String state) {
        return ResponseBean.success(sysUserRepository.findByAccountAndState(account, state));
    }

    @Override
    public Page<SysUser> findAll(Map<String, String[]> queryParameters, int pageNo, int pageSize) {
        Map<String, Object> map = SpecificationSortUtil.creat(queryParameters, SysPermission.class);
        Specification<SysUser> specification = (Specification<SysUser>) map.get(SpecificationSortUtil.SEARCHS);
        Sort sort = (Sort) map.get(SpecificationSortUtil.ORDERS);
        Pageable page = null == sort ? new PageRequest(0, 15) : new PageRequest(0, 15, sort);
        if (null == specification) {
            return sysUserRepository.findAll(page);
        } else {
            return sysUserRepository.findAll(specification, page);
        }
    }

    @Override
    public ResponseBean<SysUser> addOrUpdate(SysUserDto dto) {
        SysUser entity = sysUserMapper.dtoToEntity(dto);
        String salt = PasswordUtil.generateSalt();
        entity.setSalt(salt);
        entity.setPassword(PasswordUtil.generateMd5WithSalt(dto.getPassword(),
                dto.getAccount(), salt));
        if (StringUtils.isEmpty(entity.getState())) {
            entity.setState(UserState.NORMAL);
        }
        String organizationId = dto.getOrganizationId();
        if (!StringUtils.isEmpty(organizationId)) {
            entity.setOrganization(sysOrganizationService.findById(organizationId).getData().orElse(null));
        }
        String roleIds = dto.getRoleIds();
        if (!StringUtils.isEmpty(roleIds)) {
            Set<SysRole> sysRoles = sysRoleService.findByIds(Splitter.on(",")
                    .trimResults().splitToList(roleIds)).getData();
            if (!CollectionUtils.isEmpty(sysRoles)) {
                entity.setRoles(sysRoles);
            }
        }
        return save(entity);
    }

    @Override
    public ResponseBean<Map<String, Token>> login(String account, String password) {
        SysUser user = findByAccountAndState(account, UserState.NORMAL).getData();
        if (null == user) {
            return ResponseBean.fail("用户不存在，登录失败");
        }
        //盐（用户名+随机数）
        String salt = user.getSalt();
        //原密码
        String encodedPassword = PasswordUtil.generateMd5WithSalt(password, account, salt);
        if (user.getPassword().equals(encodedPassword)) {
            Map<String, Token> map = new HashMap<>();
            map.put("accessToken", JWTUtil.accessToken(account, user.getPassword(), user.getId()));
            map.put("refreshToken", JWTUtil.refreshToken(account, user.getPassword(), user.getId()));
            return ResponseBean.success("登录成功", map);
        } else {
            return ResponseBean.fail("密码错误，登录失败");
        }
    }

    @Override
    public ResponseBean<Map<String, Token>> refreshToken(String refreshToken) {
        String account = JWTUtil.getAccount(refreshToken);
        String userId = JWTUtil.getUserId(refreshToken);
        SysUser user = findByAccountAndState(account, UserState.NORMAL).getData();
        if (user == null) {
            return ResponseBean.fail("用户不存在，刷新token失败");
        }
        if (!userId.equals(user.getId())) {
            return ResponseBean.fail("用户不存在，刷新token失败");
        }
        if (JWTUtil.verifyRefreshToken(refreshToken, account, user.getPassword(), userId)) {
            Map<String, Token> map = new HashMap<>();
            map.put("accessToken", JWTUtil.accessToken(account, user.getPassword(), user.getId()));
            map.put("refreshToken", JWTUtil.refreshToken(account, user.getPassword(), user.getId()));
            return ResponseBean.success("刷新token成功", map);
        }
        return ResponseBean.fail("token不正确，刷新token失败");
    }

    @Override
    public ResponseBean<SysUser> updateState(String id, String state) {
        if(UserState.NORMAL.equals(state)
                ||UserState.DELETED.equals(state)
                ||UserState.DISABLED.equals(state)){
        SysUser sysUser = findById(id).getData().orElse(null);
        if (null == sysUser) {
            return ResponseBean.fail("用户不存在");
        }
        sysUser.setState(state);
        return save(sysUser);
        }else{
            return ResponseBean.fail("非法状态");
        }
    }
}
